package com.xuecheng.content.service.jobhandler;

import cn.hutool.core.bean.BeanUtil;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.feignclient.SearchServiceClient;
import com.xuecheng.content.mapper.CoursePublishMapper;
import com.xuecheng.content.model.dto.CoursePreviewDto;
import com.xuecheng.content.model.po.CourseIndex;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * @author shiminghui
 * @date 2024/9/4 10:38
 * @description: TODO
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CoursePublishTask extends MessageProcessAbstract {

    private final CoursePublishService coursePublishService;
    private final SearchServiceClient searchServiceClient;
    private final CoursePublishMapper coursePublishMapper;

    //分片任务调度
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() {

        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.debug("shardIndex=" + shardIndex + ",shardTotal=" + shardTotal);
        //参数:分片序号、分片总数、消息类型、一次最多取到的任务数量、一次任务调度执行的超时时间
        process(shardIndex, shardTotal, "course_publish", 30, 60);

    }


    //课程发布任务逻辑
    @Override
    public boolean execute(MqMessage mqMessage) {
        //获取相关的业务信息
        String businessKey1 = mqMessage.getBusinessKey1();
        Long courseId = Long.valueOf(businessKey1);

        //课程缓存(redis)
        saveCourseCache(mqMessage, courseId);
        //课程索引(elastic search)
        saveCourseIndex(mqMessage, courseId);
        //课程静态化页面
        generateCourseHtml(mqMessage, courseId);

        return true;
    }

    //课程静态化页面
    private void generateCourseHtml(MqMessage mqMessage, Long courseId) {
        //先查询任务状态,保证数据幂等性
        MqMessageService mqMessageService = this.getMqMessageService();
        Long taskId = mqMessage.getId();//任务id
        //查询任务状态
        int stageOne = mqMessageService.getStageOne(taskId);
        //任务已完成
        if (stageOne > 0) {
            log.debug("课程静态化页面任务已完成,无需执行...");
            return;
        }

        //任务未完成
        //生成静态化页面
        File file = coursePublishService.generateCourseHtml(courseId);
        if (file == null) {
            XueChengPlusException.cast("生成静态化页面失败,课程id为:" + courseId);
        }
        //上传到minio
        coursePublishService.uploadCourseHtml(courseId, file);

        //任务完成后
        mqMessageService.completedStageOne(taskId);

    }

    //课程索引(elastic search)
    private void saveCourseIndex(MqMessage mqMessage, Long courseId) {
        //先查询任务状态,保证数据幂等性
        MqMessageService mqMessageService = this.getMqMessageService();
        Long taskId = mqMessage.getId();//任务id
        //查询任务状态
        int stageTwo = mqMessageService.getStageTwo(taskId);
        //任务已完成
        if (stageTwo > 0) {
            log.debug("课程索引任务已完成,无需执行...");
            return;
        }

        //任务未完成
        //课程索引
        //从课程发布表查询数据
        CoursePublish coursePublish = coursePublishMapper.selectById(courseId);

        //数据拷贝
        CourseIndex courseIndex = new CourseIndex();
        BeanUtil.copyProperties(coursePublish, courseIndex);

        //向搜索服务发送添加索引的请求
        Boolean add = searchServiceClient.add(courseIndex);
        if (!add) {
            XueChengPlusException.cast("添加索引失败");
        }

        //任务完成后
        mqMessageService.completedStageTwo(taskId);

    }

    /**
     * 课程缓存(redis)
     *
     * @param mqMessage
     * @param courseId
     */
    private void saveCourseCache(MqMessage mqMessage, Long courseId) {
        //先查询任务状态,保证数据幂等性
        MqMessageService mqMessageService = this.getMqMessageService();
        Long taskId = mqMessage.getId();//任务id
        //查询任务状态
        int stageThree = mqMessageService.getStageThree(taskId);
        //任务已完成
        if (stageThree > 0) {
            log.debug("课程缓存任务已完成,无需执行...");
            return;
        }

        //任务未完成
        //课程缓存


        //任务完成后
        mqMessageService.completedStageThree(taskId);

    }
}
